﻿' Copyright © Microsoft Corporation.  All Rights Reserved.
' This code released under the terms of the 
' Microsoft Public License (MS-PL, http://opensource.org/licenses/ms-pl.html.)
''' <copyright file="HotspotControl.xaml.vb" company="Microsoft">
'''     Copyright © Microsoft Corporation. All rights reserved.
''' </copyright>
''' <summary>Implements the Hotspot class which listens to various mouse 
''' events and fires associated animations</summary>
''' <author>Microsoft Expression Encoder Team</author>

Imports Microsoft.VisualBasic
Imports System
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Input
Imports System.Windows.Media.Animation
Imports System.Windows.Threading
Imports System.Diagnostics
Imports System.Windows.Media

Namespace ExpressionMediaPlayer
	Partial Public Class HotspotControl
		Inherits Grid
		''' <summary>
		''' hotspot has focus
		''' </summary>
		Private m_hotspotHasFocus As Boolean
		''' <summary>
		''' timer for delay for exit animation
		''' </summary>
		Private m_timerExitAnim As DispatcherTimer
		''' <summary>
		''' Hotspot control, fires named animations on various mouse events
		''' </summary>
		Public Sub New()
			AddHandler MouseEnter, AddressOf OnMouseEnter
			AddHandler MouseLeave, AddressOf OnMouseLeave

			SetEvents(Me)

			m_timerExitAnim = New DispatcherTimer()
			AddHandler m_timerExitAnim.Tick, AddressOf ExitAnimationTimer
			Delay = 1.0
		End Sub
		''' <summary>
		''' when exit animation timer times out
		''' </summary>
		Private Sub ExitAnimationTimer(ByVal sender As Object, ByVal e As EventArgs)
			m_timerExitAnim.Stop()
			If Me.MouseLeaveAnimation IsNot Nothing Then
				Me.MouseLeaveAnimation.Begin()
			End If
		End Sub
		''' <summary>
		''' timed delay before showing exit animation
		''' </summary>
		Private privateDelay As Double
		Public Property Delay() As Double
			Get
				Return privateDelay
			End Get
			Set(ByVal value As Double)
				privateDelay = value
			End Set
		End Property
		''' <summary>
		''' Animation to fire when mouse enters hotspot
		''' </summary>
		Private privateMouseEnterAnimation As Storyboard
		Public Property MouseEnterAnimation() As Storyboard
			Get
				Return privateMouseEnterAnimation
			End Get
			Set(ByVal value As Storyboard)
				privateMouseEnterAnimation = value
			End Set
		End Property
		''' <summary>
		''' Animation to fire when mouse leaves hotspot
		''' </summary>
		Private privateMouseLeaveAnimation As Storyboard
		Public Property MouseLeaveAnimation() As Storyboard
			Get
				Return privateMouseLeaveAnimation
			End Get
			Set(ByVal value As Storyboard)
				privateMouseLeaveAnimation = value
			End Set
		End Property
		''' <summary>
		''' handle mouse entering hotspot
		''' </summary>
		Protected Overloads Sub OnMouseEnter(ByVal sender As Object, ByVal e As MouseEventArgs)
			FireEnterAnimation()
		End Sub
		''' <summary>
		''' handle mouse leaving hotspot
		''' </summary>        
		Protected Overloads Sub OnMouseLeave(ByVal sender As Object, ByVal e As MouseEventArgs)
			FireLeaveAnimation()
		End Sub
		''' <summary>
		''' is this control a child of the hotspot area
		''' </summary>
		''' <param name="dependancyObject"></param>
		''' <returns></returns>
		Private Function IsHotSpotOrChild(ByVal dependancyObjectTest As Object) As Boolean
			If dependancyObjectTest IsNot Nothing AndAlso TypeOf dependancyObjectTest Is DependencyObject Then
				Dim dependancyObject As DependencyObject = TryCast(dependancyObjectTest, DependencyObject)
				Do
					If dependancyObject Is CType(Me, DependencyObject) Then
						Return True
					End If
					dependancyObject = VisualTreeHelper.GetParent(dependancyObject)
				Loop While dependancyObject IsNot Nothing
			End If
			Return False
		End Function
		''' <summary>
		''' handle focus entering hotspot control (or any child controls)
		''' </summary>        
		Private Sub HotspotControl_GotFocus(ByVal sender As Object, ByVal e As RoutedEventArgs)
			If Not IsHotSpotOrChild(e.OriginalSource) Then
				Return
			End If
			If m_hotspotHasFocus Then
				Return
			End If
			FireEnterAnimation()
			m_hotspotHasFocus = True
		End Sub
		''' <summary>
		''' handle focus leaving hotspot control (or any child controls)
		''' </summary>
		Private Sub HotspotControl_LostFocus(ByVal sender As Object, ByVal e As RoutedEventArgs)
			Dim objectNewFocus As Object = FocusManager.GetFocusedElement()
			If IsHotSpotOrChild(objectNewFocus) Then
				Return
			End If
			FireLeaveAnimation()
			m_hotspotHasFocus = False
		End Sub
		''' <summary>
		''' set animation events for this element and all child controls
		''' </summary>
		''' <param name="elem"></param>
		Private Sub SetEvents(ByVal elem As UIElement)
			AddHandler elem.GotFocus, AddressOf HotspotControl_GotFocus
			AddHandler elem.LostFocus, AddressOf HotspotControl_LostFocus
			If TypeOf elem Is Panel Then
				For Each elemChild As UIElement In (CType(elem, Panel)).Children
					SetEvents(elemChild)
				Next elemChild
			End If
		End Sub
		''' <summary>
		''' shows the hotspot enter animation if defined
		''' </summary>
		Protected Sub FireEnterAnimation()
			If Me.MouseEnterAnimation IsNot Nothing Then
				Me.m_timerExitAnim.Stop()
				Me.MouseEnterAnimation.Begin()
			End If
		End Sub
		''' <summary>
		''' shows the hostspot leave animation if defined
		''' </summary>
		Protected Sub FireLeaveAnimation()
			If Me.MouseLeaveAnimation IsNot Nothing Then
				m_timerExitAnim.Interval = New TimeSpan(CLng(Fix(Delay * 10000000)))
				m_timerExitAnim.Start()
			End If
		End Sub
	End Class
End Namespace
